#include "ringBuffer.h"

#define ringBuffer_Next_Pos(ring_, pos_) (((pos_) + 1 == (ring_)->len) ? 0 : ((pos_) + 1))

void ringBuffer_Init(ringBuffer *ring, RING_BUFFER_DATA *buf, unsigned int len)
{
    ring->buf  = buf;
    ring->len  = len;
    ring->head = 0;
    ring->tail = 0;
}

void ringBuffer_Push_Back(ringBuffer *ring, RING_BUFFER_DATA data)
{
    unsigned int pos;

    pos = ring->tail;
    ring->buf[pos] = data;
    ring->tail = ringBuffer_Next_Pos(ring, pos);
}

RING_BUFFER_DATA ringBuffer_Get_Head(ringBuffer *ring)
{
    return ring->buf[ring->head];
}

RING_BUFFER_DATA ringBuffer_Pop_Head(ringBuffer *ring)
{
    RING_BUFFER_DATA data;
    unsigned int pos;

    pos = ring->head;
    data = ring->buf[pos];
    pos = ringBuffer_Next_Pos(ring, pos);
    ring->head = pos;

    return data;
}

unsigned int ringBuffer_Size(ringBuffer *ring)
{
    return (ring->head <= ring->tail ? (ring->tail - ring->head) : (ring->len - ring->head + ring->tail));
}

void ringBuffer_Clear(ringBuffer *ring)
{
    ring->head = 0;
    ring->tail = 0;
}
